package cn.tedu.mimall.product.service.impl;

import cn.tedu.mimall.product.service.IProductService;
import cn.tedu.mimall.product.ex.ServiceException;
import cn.tedu.mimall.product.mapper.ProductMapper;
import cn.tedu.mimall.product.mapper.ProductStateMapper;
import cn.tedu.mimall.product.pojo.dto.ProductAddNewDTO;
import cn.tedu.mimall.product.pojo.dto.ProductUpdateDTO;
import cn.tedu.mimall.product.pojo.entity.Product;
import cn.tedu.mimall.product.pojo.vo.ProductListItemVO;
import cn.tedu.mimall.product.pojo.vo.ProductStandardVO;
import cn.tedu.mimall.product.pojo.vo.ProductStateStandardVO;
import cn.tedu.mimall.product.repo.IProductRedisRepository;
import cn.tedu.mimall.product.web.ServiceCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * 商品相关业务处理实现类
 *
 * @author rz
 * @version 0.0.1
 */
@Service
@Slf4j
public class ProductServiceImpl implements IProductService {

    @Autowired
    ProductMapper productMapper;

    @Autowired
    ProductStateMapper productStateMapper;

    @Autowired
    IProductRedisRepository productRedisRepository;

    @Override
    public void addNew(ProductAddNewDTO productAddNewDTO) {
        log.debug("开始处理添加商品的业务,参数{}", productAddNewDTO);
        //检查商品是否存在
        String title = productAddNewDTO.getTitle();
        int count = productMapper.countByTitle(title);
        if(count != 0){
            throw new ServiceException(ServiceCode.ERR_CONFLICT, "商品已存在!");
        }
        //商品不存在,添加商品信息
        //将productAddNewDTO中数据填入product
        Product product = new Product();
        BeanUtils.copyProperties(productAddNewDTO, product);
        int rows = productMapper.insert(product);
        //判断添加是否成功
        if(rows!=1){
            //添加失败
            throw new ServiceException(ServiceCode.ERR_INSERT, "添加失败!请稍后再试!");
        }
        //添加成功
        log.debug("添加成功,受影响行数:{},数据:{}", rows, product);
    }

    @Override
    public void deleteById(Long id) {
        log.debug("开始处理根据商品id删除商品信息的业务,参数:{}", id);
        //判断数据是否存在
        ProductStandardVO product = productMapper.getStandardById(id);
        if(product==null){
            //数据不存在
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, "数据不存在!");
        }
        //数据存在,删除数据
        int rows = productMapper.deleteById(id);
        if(rows!=1){
            //删除失败
            throw new ServiceException(ServiceCode.ERR_DELETE, "删除失败!");
        }
        //删除成功!
        log.debug("删除成功,受影响行数:{}", rows);
    }

    @Override
    public void updateInfoById(Long id, ProductUpdateDTO productUpdateDTO) {
        log.debug("开始处理根据商品id修改商品信息的业务,商品id:{},参数:{}", id, productUpdateDTO);
        Product product = new Product();
        product.setId(id);
        BeanUtils.copyProperties(productUpdateDTO, product);
        int rows = productMapper.updateById(product);
        if(rows!=1){
            //修改失败
            throw new ServiceException(ServiceCode.ERR_UPDATE, "修改失败!");
        }
        //修改成功
        log.debug("修改成功,受影响行数:{}", rows);
    }

    @Override
    public void updateProductStateById(Long id, Long productStateId) {
        log.debug("开始处理根据商品id修改商品状态的业务,商品id{},参数{}", id, productStateId);
        //判断商品是否存在
        ProductStandardVO product = productMapper.getStandardById(id);
        if(product==null){
            //商品不存在
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, "商品不存在!");
        }
        //判断商品状态是否存在
        ProductStateStandardVO state = productStateMapper.getStandardById(productStateId);
        log.debug("商品状态:{}", state.getName());
        if(state==null){
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, "商品状态不存在!");
        }
        productMapper.updateProductState(id, productStateId);
        log.debug("修改商品状态成功!");
    }

    @Override
    public ProductStandardVO getStandardById(Long id) {
        log.debug("开始处理根据id查询商品详情业务,id:{}", id);
        ProductStandardVO product = productRedisRepository.get(id);
        if(product==null){
            //未找到商品
            throw new ServiceException(ServiceCode.ERR_SELECT, "商品不存在");
        }
        log.debug("根据id查询成功");
        return product;
    }

    @Override
    public List<ProductListItemVO> list() {
        log.debug("开始处理查询商品列表业务");
        List<ProductListItemVO> list = productRedisRepository.list();
        log.debug("查询商品列表成功");
        return list;
    }

    @Override
    public List<ProductListItemVO> listByClassifyId(Long id) {
        List<ProductListItemVO> list = productMapper.listByClassifyId(id);
        return list;
    }

    @Override
    public List<ProductListItemVO> listByTitle(String title) {
        List<ProductListItemVO> list = productMapper.listByTitle(title);
        return list;
    }

    @Override
    public List<ProductListItemVO> listOrderByPrice() {
        List<ProductListItemVO> list = productRedisRepository.list();
        Collections.sort(list, new Comparator<ProductListItemVO>() {
            @Override
            public int compare(ProductListItemVO o1, ProductListItemVO o2) {
                return o1.getPrice().intValue()-o2.getPrice().intValue();
            }
        });
        return list;
    }

    @Override
    public List<ProductListItemVO> listOrderByPriceDesc() {
        List<ProductListItemVO> list = productRedisRepository.list();
        Collections.sort(list, new Comparator<ProductListItemVO>() {
            @Override
            public int compare(ProductListItemVO o1, ProductListItemVO o2) {
                return o2.getPrice().intValue()-o1.getPrice().intValue();
            }
        });
        return list;
    }

    @Override
    public void rebuildCache() {
        log.debug("删除Redis中原有的品牌数据");
        productRedisRepository.deleteAll();

        log.debug("从MySQL中读取品牌列表");
        List<ProductListItemVO> products = productMapper.list();

        log.debug("将品牌列表写入到Redis");
        productRedisRepository.save(products);

        log.debug("逐一根据id从MySQL中读取品牌详情，并写入到Redis");
        for (ProductListItemVO item : products) {
            ProductStandardVO brand = productMapper.getStandardById(item.getId());
            productRedisRepository.save(brand);
        }
    }
}
